package com.naiterui.ehp.bs.agent.service.impl;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.agent.vo.CustomAppDetailVO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.bo.agent.AgentCustomBO;
import com.naiterui.ehp.bp.bo.agent.CustomOrderInfoBO;
import com.naiterui.ehp.bp.bo.agent.DoctorDetailBO;
import com.naiterui.ehp.bp.bo.statistics.AsOrderRecordBO;
import com.naiterui.ehp.bp.bo.statistics.CustomOrderReportBO;
import com.naiterui.ehp.bp.bo.statistics.CustomProductReportBO;
import com.naiterui.ehp.bp.bo.statistics.CustomRecipelConsultReportBO;
import com.naiterui.ehp.bp.constants.OrderStatusEnum;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.biz.TitleUtil;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bs.agent.entity.AgAgent;
import com.naiterui.ehp.bs.agent.entity.AgAgentCustom;
import com.naiterui.ehp.bs.agent.entity.AgCustomSummary;
import com.naiterui.ehp.bs.agent.entity.Order;
import com.naiterui.ehp.bs.agent.feign.IB2cFeignClient;
import com.naiterui.ehp.bs.agent.feign.ICmsapiFeignClient;
import com.naiterui.ehp.bs.agent.feign.IDoctorFeignClient;
import com.naiterui.ehp.bs.agent.feign.ISearchFeignClient;
import com.naiterui.ehp.bs.agent.po.CustomPagePO;
import com.naiterui.ehp.bs.agent.repository.IAgAgentCustomRepository;
import com.naiterui.ehp.bs.agent.repository.IAgAgentRepository;
import com.naiterui.ehp.bs.agent.repository.IAgCustomSummaryRepository;
import com.naiterui.ehp.bs.agent.repository.IOrderRepository;
import com.naiterui.ehp.bs.agent.service.ICustomService;
import com.naiterui.ehp.bs.agent.util.Tools;
import com.naiterui.ehp.bs.agent.vo.AgentCustomItemVO;
import com.naiterui.ehp.bs.agent.vo.CustomDetailVO;
import com.naiterui.ehp.bs.agent.vo.CustomOrderListVO;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 客户管理
 * 
 * @author yangfuya
 * @since 2022/2/18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomServiceImpl implements ICustomService {
    private final ICmsapiFeignClient cmsapiFeignClient;
    private final ISearchFeignClient searchFeignClient;
    private final IAgAgentCustomRepository agAgentCustomRepository;
    private final IB2cFeignClient ib2cFeignClient;
    private final IAgAgentRepository agAgentRepository;
    private final IDoctorFeignClient doctorFeignClient;
    private final IAgCustomSummaryRepository agCustomSummaryRepository;
    private final IOrderRepository orderRepository;

    @Override
    public PageVO<CustomOrderListVO> getOrderList(PageParamVO paramVO, Long customId, String orderSn)
        throws BusinessException {
        PageVO<AsOrderRecordBO> page =
            searchFeignClient.findOrderPage(customId, orderSn, paramVO.getPage(), paramVO.getNum());
        List<AsOrderRecordBO> result = page.getResult();
        if (CollUtil.isEmpty(result)) {
            return PageVO.newBuilder().pageNo(page.getPageNo()).pageSize(page.getPageSize())
                .totalCount(page.getTotalCount()).offset(page.getOffset()).result(Collections.emptyList()).build();
        }
        Set<String> orderSns = result.stream().map(AsOrderRecordBO::getOrderSn).collect(Collectors.toSet());
        List<Order> orderList = orderRepository.findByOrderSnIn(orderSns);
        Map<String, Order> orderMap = orderList.stream().collect(Collectors.toMap(Order::getOrderSn, a -> a));
        return PageVO.newBuilder().pageNo(page.getPageNo()).pageSize(page.getPageSize())
            .totalCount(page.getTotalCount()).offset(page.getOffset())
            .result(result.stream()
                .map(r -> {
                    Integer orderStatus = orderMap.get(r.getOrderSn()).getOrderStatus();
                    OrderStatusEnum orderStatusEnum = OrderStatusEnum.getFrontDeskStatus(orderStatus);
                    return CustomOrderListVO.builder().orderSn(r.getOrderSn()).orderPrice(r.getOrderPrice())
                        .orderTime(r.getOrderTime()).productNumber(r.getProductNumber()).orderStatus(orderStatus)
                        .statusName(orderStatusEnum.getStatusDescribe()).build();

                })
                .collect(Collectors.toList()))
            .build();
    }

    @Override
    public CustomRecipelConsultReportBO getRecipelAndConsult(Long customId, Integer reportType, String reportDate) {
        return cmsapiFeignClient.getRecipelAndConsult(customId, reportType, reportDate);
    }

    @Override
    public CustomProductReportBO getProduct(Long customId, Integer reportType, String reportDate) {
        return cmsapiFeignClient.getProduct(customId, reportType, reportDate);
    }

    @Override
    public CustomOrderReportBO getOrder(Long customId, Integer reportType, String reportDate) {
        return cmsapiFeignClient.getOrder(customId, reportType, reportDate);
    }

    @Override
    public AgentCustomBO getAgentCustomByDoctorId(Long doctorId) {
        AgAgentCustom agentCustom = agAgentCustomRepository.findFirstByDoctorId(doctorId);
        if (agentCustom == null) {
            return null;
        }
        return AgentCustomBO.builder().agentId(agentCustom.getAgentId()).doctorId(agentCustom.getDoctorId())
            .areaId(agentCustom.getAreaId()).provinceAreaId(agentCustom.getProvinceAreaId())
            .starLev(agentCustom.getStarLev()).build();
    }

    @Override
    public CustomOrderInfoBO getOrderDetail(String orderSn) throws BusinessException {
        return this.ib2cFeignClient.getOrderDetailByOrderSn(orderSn);
    }

    @Override
    public PageVO<AgentCustomItemVO> findCustomPage(PageParamVO pageParamVO, CustomPagePO customPagePO) {

        String orderCol;
        if (customPagePO.getOrderCol() == null || customPagePO.getOrderCol() == CustomPagePO.ORDER_COL_INVITE_TIME){
            orderCol = "inviteTime";
        }else if (customPagePO.getOrderCol() == CustomPagePO.ORDER_COL_STAR_LEV){
            orderCol = "starLev";
        }else {
            orderCol = "prescriptionTotal";
        }
        Sort.Direction direction = Sort.Direction.DESC;
        if (customPagePO.getOrderType() != null && customPagePO.getOrderType() == 1){
            direction = Sort.Direction.ASC;
        }
        Sort sort = Sort.by(direction, orderCol);
        Date startTime = null;
        if (customPagePO.getType() != null && customPagePO.getType() == CustomPagePO.TYPE_YESTERDAY) {
            startTime = DateUtil.getStartTime(null).getTime();
        }else{
            startTime = new Date();
        }

        Page<Map<String, Object>> dbPage = agAgentCustomRepository.findCustomPage(customPagePO.getAgentId(), startTime, pageParamVO.getPageable(sort));
        List<AgentCustomItemVO> resultList = dbPage.getContent().stream().map(beanMap -> {
            AgentCustomItemVO itemVO = BeanUtil.mapToBean(beanMap, AgentCustomItemVO.class, true);
            itemVO.setHeadUrl(Tools.getImagePath(itemVO.getHeadUrl()));
            itemVO.setCustomTitle(Optional.ofNullable(itemVO.getCustomTitle()).map(NumberUtil::parseInt).map(TitleUtil::getTitle).orElse(""));
            itemVO.setAuthStatus(itemVO.getAuthStatus() != null && itemVO.getAuthStatus() == 2 ? 1 : 0);
            return itemVO;
        }).collect(Collectors.toList());
        return PageVO.newBuilder().pageNo(pageParamVO.getPage()).pageSize(pageParamVO.getNum())
                .totalCount((int)dbPage.getTotalElements()).result(resultList).build();
    }

    @Override
    public void updateStarLev(Long agentId, Long customId, Integer starLev) throws BusinessException {
        AgAgent dbAgent = agAgentRepository.get(agentId);
        if (dbAgent == null){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        AgAgentCustom agentCustom = agAgentCustomRepository.findByAgentIdAndDoctorId(agentId, customId);
        if (agentCustom == null){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        agentCustom.setStarLev(starLev);
        agAgentCustomRepository.update(agentCustom);
    }

    @Override
    public CustomDetailVO getDetail(Long agentId, Long customId) throws BusinessException {
        AgAgentCustom agentCustom = agAgentCustomRepository.findFirstByDoctorId(customId);
        if (agentCustom == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        CustomDetailVO detailVO = new CustomDetailVO();
        detailVO.setStarLev(agentCustom.getStarLev());
        detailVO.setInviteTime(agentCustom.getCreatedAt());
        DoctorDetailBO doctor = doctorFeignClient.getUserById(customId);
        detailVO.setCustomId(customId);
        detailVO.setCustomName(doctor.getName());
        detailVO.setDepartmentName(doctor.getDepartment());
        detailVO.setCustomTitle(doctor.getTitle());
        detailVO.setCustomPhone(doctor.getPhone());
        detailVO.setHospitalName(doctor.getHospitalName());
        detailVO.setHeadUrl(doctor.getHeaderImageUrl());
        AgCustomSummary customSummary = agCustomSummaryRepository.findFirstByDoctorId(customId);
        if (customSummary != null) {
            detailVO.setConsultTotal(customSummary.getConsultTotal() + customSummary.getVideoTotal());
            detailVO.setPrescriptionTotal(customSummary.getRecipelTotal());
            detailVO.setRepeatTotal(customSummary.getRepeatNumber());
            detailVO.setUnpayPrescriptionTotal(customSummary.getUnpaidNumber());
            detailVO.setPayPrescriptionTotal(customSummary.getPaidNumber());
            detailVO.setDrugAmount(customSummary.getOrderPriceTotal());
        } else {
            detailVO.setConsultTotal(0);
            detailVO.setPrescriptionTotal(0);
            detailVO.setRepeatTotal(0);
            detailVO.setUnpayPrescriptionTotal(0);
            detailVO.setPayPrescriptionTotal(0);
            detailVO.setDrugAmount(0);
        }
        detailVO.setPatientTotal(doctor.getPatientTotal());
        detailVO.setPraiseRate(doctor.getPraiseRate());
        detailVO.setConsultMessageCharge(doctor.getConsultMessageCharge());
        detailVO.setConsultVideoCharge(doctor.getConsultVideoCharge());
        detailVO.setComplainCnt(doctor.getComplainCnt());
        return detailVO;
    }

    @Override
    public CustomAppDetailVO getCustomAppDetail() {
        CustomAppDetailVO detailVO = new CustomAppDetailVO();
        String iosUrl = ConfigUtil.getString("custom.app.ios.url");
        String androidURL = ConfigUtil.getString("custom.app.android.url");
        detailVO.setIosUrl(iosUrl == null ? "" : iosUrl);
        detailVO.setAndroidUrl(androidURL == null ? "" : androidURL);
        return detailVO;
    }
}
